/*
拦截重写vue路由，提供滑动动画效果，记录页面位置
*/
import Nav from './nav';
import './ctp-router.css';

function CtpRouter(Vue) {
  Vue.prototype.$ctpRouter = {
    tn: 'slide', // 动画名
    keepAlives: [], // keepAlive存储
  };

  this.stack = [];
  this.PAGEKEY = new Date().getTime();

  this.createPageKey = () => {
    this.PAGEKEY += 1;
    return this.PAGEKEY.toString();
  };

  this.findStackIndex = pageKey => this.stack.findIndex(item => item === pageKey);

  this.pushStack = (pageKey) => {
    const index = this.findStackIndex(pageKey);
    this.stack.slice(0, index + 1);
    this.stack.push(pageKey);
  };

  this.clearStack = (pageKey) => {
    if (pageKey) {
      for (let i = 0; i < this.stack.length; i += 1) {
        if (pageKey === this.stack[i]) {
          this.stack.splice(i, 1);
          break;
        }
      }
    } else {
      this.stack = [];
    }
  };

  this.rewriteRouter = (router) => {
    ['push', 'replace'].forEach((method) => {
      const func = router[method].bind(router);
      router[method] = (location, onComplete, onAbort) => {
        const obj = {};
        if (typeof location !== 'object') {
          obj.path = location;
        } else {
          Object.assign(obj, location);
        }
        if (!obj.query) {
          obj.query = {};
        }
        if (method === 'push') {
          obj.query.$page_key = this.createPageKey();
          this.pushStack(obj.query.$page_key);
        }
        if (method === 'replace') {
          obj.query.$replace = true;
        }
        func(obj, onComplete, onAbort);
      };
    });
  };

  this.setKeepAlive = (router) => {
    const routes = router.options.routes;
    if (routes && routes.length > 0) {
      routes.forEach((route) => {
        const meta = route.meta;
        if (meta && meta.keepAlive) {
          Vue.prototype.$ctpRouter.keepAlives.push(route.name);
        }
      });
    }
  };

  this.setTransition = (from, to) => {
    const fromIndex = this.findStackIndex(from.query.$page_key);
    const toIndex = this.findStackIndex(to.query.$page_key);
    if (fromIndex < toIndex) { // enter
      Vue.prototype.$ctpRouter.tn = 'sild';
    } else if (fromIndex > toIndex) { // leave
      Vue.prototype.$ctpRouter.tn = 'sild1';
    } else {
      Vue.prototype.$ctpRouter.tn = 'none'; // replace则不做任何动画
    }
  };

  this.storeFromScrollTop = (vm, from) => {
    const scrollContainer = vm.$refs.scrollContainer;
    if (scrollContainer && from.meta) {
      from.meta.scrollTop = scrollContainer.scrollTop;
    }
  };

  // 跳转时，设置to页面的已记录的高度（来自于storeFromScrollTop）
  this.reStoreToScrollTop = (vm, to) => {
    const scrollContainer = vm.$refs.scrollContainer;
    if (scrollContainer && to.meta && to.meta.scrollTop) {
      scrollContainer.scrollTop = to.meta.scrollTop;
    }
  };
}
export default (Vue, router) => {
  const ctpRouter = new CtpRouter(Vue);
  ctpRouter.setKeepAlive(router);
  ctpRouter.rewriteRouter(router);

  Vue.component(Nav.name, Nav);

  Vue.mixin({
    beforeRouteEnter(to, from, next) {
      if (!to.query.$page_key) { // 首次进入的时候没有$page_key
        const obj = Object.assign({}, to);
        obj.replace = true;
        obj.query.$page_key = ctpRouter.createPageKey();
        ctpRouter.pushStack(obj.query.$page_key);
        next(obj);
      } else {
        next((vm) => {
          ctpRouter.reStoreToScrollTop(vm, to);
        });
      }
    },
    beforeRouteLeave(to, from, next) {
      if (to.query.$replace) {
        to.query.$page_key = from.query.$page_key;
        delete to.query.$replace;
        const obj = Object.assign({}, to);
        obj.replace = true;
        next(obj);
        return;
      }
      ctpRouter.storeFromScrollTop(this, from); // 记录离开时的位置
      ctpRouter.setTransition(from, to); // 设置动画
      next();
    },
  });
};
